package com.kot.backend.consumer;

import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.kot.backend.consumer.utils.JwtAuthentication;

import com.kot.backend.mapper.MessageMapper;
import com.kot.backend.mapper.UserMapper;
import com.kot.backend.pojo.Message;
import com.kot.backend.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

@Component
@ServerEndpoint("/websocket/message/{token}")
public class MessageWebSocketServer {
    public static ConcurrentHashMap<Integer, MessageWebSocketServer> users = new ConcurrentHashMap<>();
    public static List<Message> messages = new ArrayList<>();
    /**********因为websocket不是spring组件，所以不能直接单例注入，需要在setter注入静态变量****/
    public static UserMapper userMapper = null;//用类名来访问
    public static MessageMapper messageMapper = null;
    @Autowired
    public void setUserMapper(UserMapper userMapper){
        MessageWebSocketServer.userMapper = userMapper;//用类名来访问
    }

    @Autowired
    public void setUserMapper(MessageMapper messageMapper){
        MessageWebSocketServer.messageMapper = messageMapper;//用类名来访问
    }

    /************注入在上面****************/

    public static Integer Max_Count = 30;
    private Session session = null;//不同于http协议中的session，每个链接都是用session来维护

    private User user = null;


    @OnOpen
    public void onOpen(Session session, @PathParam("token") String token) throws IOException {
        this.session = session;
        Integer userId = JwtAuthentication.getUserId(token);//调用工具类获取UserId
        User user0 = userMapper.selectById(userId);
        this.user = user0;
        if (this.user != null) {
            users.put(userId, this);//用户存在，就是合法建立连接
        } else {
            this.session.close();//用户不合法，直接关闭连接
        }

        //第一次更新聊天信息
        MessageWebSocketServer.messages = messageMapper.selectList(
                new QueryWrapper<Message>()
                        .orderByDesc("id")
                        .last("limit 10")
        );

        //翻转
        int start = 0;
        int end = MessageWebSocketServer.messages.size() - 1;
        while (start < end) {
            Message temp = MessageWebSocketServer.messages.get(start);
            MessageWebSocketServer.messages.set(start, MessageWebSocketServer.messages.get(end));
            MessageWebSocketServer.messages.set(end, temp);
            start++;
            end--;
        }


    }

    @OnClose
    public void onClose() {
        if (this.user != null) {
            users.remove((this.user.getId()));//从全局哈希表中删除该链接
        }
    }

    public void send(String content){

        JSONObject resp = new JSONObject();

        System.out.println("content="+content);
        Message m = new Message(null,content,this.user.getId(),this.user.getPhoto(),new Date());
        messageMapper.insert(m);

        MessageWebSocketServer.messages.add(m);

        resp.put("event","send");
        resp.put("message",MessageWebSocketServer.messages);

        MessageWebSocketServer.users.forEach((key,value)->{//对每个连接用户发送聊天信息
                value.sendMessage( resp.toJSONString() );
        });
    }
    public void init(){
        JSONObject resp = new JSONObject();
        resp.put("event","init");
        resp.put("message",MessageWebSocketServer.messages);
        resp.put("user_count",MessageWebSocketServer.users.size());

        MessageWebSocketServer.users.forEach((key,value)->{//对每个连接用户发送聊天信息
            value.sendMessage( resp.toJSONString() );
        });

    }
    @OnMessage
    public void onMessage(String message, Session session) {//当作路由，根据从前端传来的message判断之后执行哪一个函数

        JSONObject data = JSONObject.parseObject(message);//字符串转换成json

        String event = data.getString("event");
        System.out.println("event="+event);
        if("send".equals(event)){
            String content = data.getString("content");
            send(content);
        }else{
            init();
        }
    }

    @OnError
    public void onError(Session session, Throwable error) {
        error.printStackTrace();
    }

    public void sendMessage(String message){//自定义一个发送信息的函数（websocket都是异步通信过程，所以发信息要加锁）
        synchronized (this.session) { //加锁
            try {
                this.session.getBasicRemote().sendText(message); //从后端向当前链接发送信息
            } catch (IOException e) { //IO异常
                e.printStackTrace();
            }
        }
    }
}
